var gulp = require('gulp')
var del = require('del')
var webpack = require('webpack')
var getConfig = require('./webpack.config')
var fs = require('fs')
var express = require('express')
var webpackDevMiddleware = require('webpack-dev-middleware')
var webpackHotMiddleware = require('webpack-hot-middleware')
var webpack = require('webpack')
var path = require('path')
var app = express()
var ip = require('ip')
var open = require('open')
var replace = require('gulp-replace')
var sourcePath = 'src'
var distPath = 'dist'
var argv = require('yargs').argv
const { exec } = require('child_process')

//版本号
const VERSION = '1'
// 获取当前日期
const date = new Date()
const year = date.getFullYear();
const month = date.getMonth() + 1;
const day = date.getDate();

const TODAY = `${year}-${month < 10 ? '0' + month : month}-${day < 10 ? '0' + day : day}`
const CONFIG = require('./src/lib/config')

//生成如右的entry ./src/pages/PickUp/index.js
function makeEntry(page_list, task_type) {
    const entries = page_list.reduce((origin, page) => {
        if (page !== '.DS_Store') {
            const entry = '../src/pages/' + page + '/index.js';
            if (task_type === 'PACK') {
                origin[page] = [entry];
            } else if (task_type === 'SERVER') {
                origin[page] = ['webpack-hot-middleware/client?path=/__webpack_hmr&timeout=20000', entry];
            }
        }
        return origin;
    }, {});

    return entries;
}

//监听每个页面的变化
function listen(page_list) {
    page_list.forEach(function (page) {
        var page_url = '/' + page

        app.get(page_url, function (req, res) {
            res.setHeader('Access-Control-Allow-Origin', '*')
            res.sendfile('./html/' + page + '.html')
        })
    })
}

//上传 dist 文件里的内容
function scp() {
    console.log(`上传 dist 文件里的内容`)
    if (!CONFIG.path) {
        console.log('production 上传失败')
        return;
    }
    const cmd = `scp -r ${path.join(__dirname, 'dist')}  ${CONFIG.path}`
    console.log(cmd)
    exec(cmd, (error, stdout, stderr) => {
        if (error) {
            console.error(`exec error: ${error}`)
            return
        }
        console.log(`stdout: ${stdout}`)
        console.log(`stderr: ${stderr}`)
        console.log(`上传完毕`)
    })
}

function execCmd(cmd) {
    return new Promise((resolve, reject) => {
        exec(cmd, (error, stdout, stderr) => {
            if (error) {
                console.error(`exec error: ${error}`)
                reject()
                return
            }
            console.log(`stdout: ${stdout}`)
            console.log(`stderr: ${stderr}`)
            console.log('上传完毕')
            resolve()
        })
    })
}

//上传 dist 文件里的内容
function scpProd() {
    console.log(`上传 html 文件里的内容()`)
    const build_html = path.join(__dirname, `build/v${TODAY}_HTML`)
    const build_js = path.join(__dirname, `build/v${TODAY}`)
    const remote_105 = `web@10.1.0.105:/tmp/`
    const remote_106 = `web@10.1.0.106:/tmp/`

    const mkdir105 = `ssh web@10.1.0.105 'mkdir /tmp/v${TODAY}_HTML /tmp/v${TODAY}'`
    const mkdir106 = `ssh web@10.1.0.106 'mkdir /tmp/v${TODAY}_HTML'`
    const cmd1 = `scp -r ${build_html}  ${remote_105}`
    const cmd2 = `scp -r ${build_html}  ${remote_106}`
    const cmd3 = `scp -r ${build_js}  ${remote_105}`
    execCmd(mkdir105)
        .then(() => execCmd(cmd1))
        .then(() => execCmd(mkdir106))
        .then(() => execCmd(cmd2))
        .then(() => execCmd(cmd3))
}

gulp.task('scp_dev', function (cb) {
    scp()
})

gulp.task('scp_prod', function (cb) {
    scpProd()
})

gulp.task('pack_single_scp', ['pack_single'], function (cb) {
    scp()
})

gulp.task('default', function (cb) {
    var des = `
    当前日期 '${TODAY}'
    当前环境为：${CONFIG.ENVIRONMENT}
    当前 DEV_SERVER 为：${CONFIG.DEV_SERVER}
    -------------------本地开发-------------------
    gulp server   ===> 启动服务
    -------------------测试环境-------------------
    gulp pack_dev ===> 全局打包，会 copy 所有 html 进 dist
    gulp scp_dev      ===> 上传 dist 文件夹至开发环境
    -------------------线上环境-------------------
    gulp pack_prod ===> 执行 tpl 和 pack_pro
    gulp scp_prod ===> 上传 html/css/js 文件至线上环境
    `
    console.log(des)
})

gulp.task('pack_single', function (cb) {
    console.log(`正在进行测试环境单个页面的 JS/CSS 打包，涉及${argv.pages}`)
    var pages = argv.pages.split(',')
    var entries = makeEntry(pages, 'PACK')
    var webpack_config = getConfig('PACK')
    webpack_config.plugins.push(
        //压缩，会加长打包时间
        new webpack.optimize.UglifyJsPlugin({
            compress: {
                warnings: false
            }
        })
    )
    var config = Object.assign(webpack_config, {
        entry: entries,
        devtool: undefined,
        output: {
            path: path.join(__dirname, 'dist'),
            filename: '[name].min.js',
        }
    })
    webpack(config, cb)
})

gulp.task('clean', function (cb) {
    return del([distPath], cb)
})

gulp.task('copyHtml', function () {
    return gulp.src([
        path.join(sourcePath, '..', 'html', '*.*')
    ]).pipe(gulp.dest(distPath))
})

gulp.task('copyHtmlPure', function () {
    return gulp.src([
        path.join(sourcePath, '..', 'htmlpure', '*.*')
    ]).pipe(gulp.dest(distPath))
})

gulp.task('pack_dev', ['copyHtml', 'copyHtmlPure'], function (cb) {

    console.log('将适用于测试环境的 HTML/CSS/JS 打包进 dist')
    //获取所有 pages 路径下的文件名称数组
    var pages = fs.readdirSync(path.join(sourcePath, 'pages'))
    var entries = makeEntry(pages, 'PACK')
    var webpack_config = getConfig('PACK')
    webpack_config.plugins.push(
        //压缩，会加长打包时间
        new webpack.optimize.UglifyJsPlugin({
            compress: {
                warnings: false
            }
        })
    )
    var config = Object.assign(webpack_config, {
        entry: entries,
        devtool: undefined,
        output: {
            path: path.join(__dirname, 'dist'),
            filename: '[name].min.js',
        }
    });
    webpack(config, cb)
})

//生成线上 HTML
gulp.task('tpl', function (cb) {
    console.log(`将适用于线上环境所有页面的 HTML 打包进 build/v${TODAY}_HTML/`)
    console.log(`文件版本号${VERSION}`)
    var pages = fs.readdirSync(path.resolve(__dirname, 'html'))
    pages.forEach(item => {
        if (item === '.DS_Store') {
            return
        }
        var name = item.split('.')[0]
        var url = `//cdn2.jinlb.cn/web/weixin/v${TODAY}/`
        var src = ['html/' + name + '.html']
        var from_css = name + '.min.css'
        var to_css = url + name + `v${VERSION}.min.css`
        var from_js = name + '.min.js'
        var to_js = url + name + `v${VERSION}.min.js`

        gulp.src(src)
            .pipe(replace(from_css, to_css))
            .pipe(replace(from_js, to_js))
            .pipe(gulp.dest(`build/v${TODAY}_HTML`))
    })
})

gulp.task('copyProdHtmlPure', function (cb) {
    return gulp.src([
        path.join(sourcePath, '..', 'htmlpure', '*.*')
    ]).pipe(gulp.dest(`build/v${TODAY}_HTML`))
})

//生成线上 JS CSS
gulp.task('pack', function (cb) {
    console.log(`将适用于线上环境所有页面的 CSS/JS 打包进 build/v${TODAY}/`)
    console.log(`文件版本号${VERSION}`)
    //获取所有 pages 路径下的文件名称数组
    var pages = fs.readdirSync(path.join(sourcePath, 'pages'))
    var entries = makeEntry(pages, 'PACK')
    var webpack_config = getConfig('PACK', VERSION)
    webpack_config.plugins.push(
        //压缩，会加长打包时间
        new webpack.optimize.UglifyJsPlugin({
            compress: {
                warnings: false
            }
        })
    );

    var config = Object.assign(webpack_config, {
        entry: entries,
        devtool: undefined,
        //devtool: 'source-map',
        output: {
            path: path.join(__dirname, `build/v${TODAY}/`),
            filename: `[name]v${VERSION}.min.js`,
        }
    })
    webpack(config, cb)
})

//一键上线
gulp.task('pack_prod', ['pack', 'tpl', 'copyProdHtmlPure'], function (cb) {
    cb()
})

gulp.task('server', function (cb) {

    var pages = fs.readdirSync(path.join(sourcePath, 'pages'))
    var entries = makeEntry(pages, 'SERVER')
    var webpack_config = getConfig('SERVER')
    var config = Object.assign(webpack_config, {
        type: 'SERVER',
        entry: entries,
        devtool: undefined,
        output: {
            path: path.join(__dirname),
            filename: '[name].min.js',
            publicPath: '/',
        },
    })
    var compiler = webpack(config)

    app.use(webpackDevMiddleware(compiler, {
        noInfo: true,
        publicPath: '/',
        stats: {
            colors: true,
        },
    }))

    app.use(webpackHotMiddleware(compiler, {
        log: console.log,
        path: '/__webpack_hmr',
        heartbeat: 10 * 1000,
    }))

    listen(pages)

    var server = app.listen(3000, function () {
        var host = ip.address() || server.address().address
        var port = server.address().port
        console.log('Example app listening at http://%s:%s', ip.address(), port)
        var url = 'http://' + host + ':' + port + '/test'
        open(url)
    })
    cb()
})